package org.ethereum.net.stats;

import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

public class KPICollector {

	private final String kpiSetName;
	
	private final SortedMap<String, SingleKPI> kpis = new TreeMap<String, SingleKPI>();
	
	private final Map<String, KPICollector> collectors = new HashMap<String, KPICollector>();
	
	private static final KPICollector defaultCollector = new KPICollector("default");
	
	public static KPICollector getDefault() {
		return defaultCollector;
	}
	
	
	public KPICollector(String kpiSetName) {
		this.kpiSetName = kpiSetName;
	}
	
	public void addKPI(String kipName, SingleKPI kipInfo) {
		this.kpis.put(kipName, kipInfo);
	}
	
	public boolean hasKPI(String kipName) {
		return this.kpis.containsKey(kipName);
	}
	
	public void updateKPI(String kipName, long value) {
		if (this.kpis.containsKey(kipName)) {
			SingleKPI kip = this.kpis.get(kipName);
			if (kip instanceof ConcludeStats) {
				((ConcludeStats)kip).addNew(value);
			} else if (kip instanceof TimeRangesStats) {
				((TimeRangesStats)kip).arrange(value);
			} else if (kip instanceof ThroughputStats) {
				((ThroughputStats)kip).increment();
				((ThroughputStats)kip).updateAndGetThroughput();
			} 
		}
	}
	
	/**
	 * Get all information.
	 * 
	 * @return
	 */
	public SortedMap<String, SingleKPI> getAllKIPs() {
		return this.kpis;
	}
	
	public SingleKPI getKPI(String kpiName) {
		return this.kpis.get(kpiName);
	}
	
	public String getKpiSetName() {
		return this.kpiSetName;
	}
	
	@Override
	public String toString() {
		if (!collectors.isEmpty()) {
			return "collector name: " + this.kpiSetName + ", kpi set: " + kpis.toString() + ", sub collectors: " + collectors;
		}
		return "collector name: " + this.kpiSetName + ", kpi set: " + kpis.toString();
	}
	
	public JSONObject toJson() {
		JSONObject json = new JSONObject();
		try {
			json.put("KPIName", this.kpiSetName);
			JSONArray array = new JSONArray();
			for (SingleKPI kip: kpis.values()) {
				array.add(kip.toJson());
			}
			json.put("kpis", array);
			if (!collectors.isEmpty()) {
				json.put("SubCollectors", collectors.toString());
			}
		} catch (Exception e) {
		}
		return json;
	}
	
	
	public void registerCollector(String name, KPICollector collector) {
		collectors.put(name, collector);
	}
	
	public boolean hasCollector(String name) {
		return collectors.containsKey(name);
	}
	
	public KPICollector getCollector(String name) {
		return collectors.get(name);
	}
}
